1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkElementIndex;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 import static com.google.common.base.Preconditions.checkPositionIndexes;
22 import static com.google.common.collect.ObjectArrays.arraysCopyOf;
23 import static com.google.common.collect.ObjectArrays.checkElementsNotNull;
24
25 import com.google.common.annotations.GwtCompatible;
26
27 import java.io.InvalidObjectException;
28 import java.io.ObjectInputStream;
29 import java.io.Serializable;
30 import java.util.Collection;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.RandomAccess;
34
35 import javax.annotation.Nullable;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 @GwtCompatible(serializable = true, emulated = true)
62 @SuppressWarnings("serial")
63 public abstract class ImmutableList<E> extends ImmutableCollection<E>
64 implements List<E>, RandomAccess {
65
66 private static final ImmutableList<Object> EMPTY =
67 new RegularImmutableList<Object>(ObjectArrays.EMPTY_ARRAY);
68
69
70
71
72
73
74
75 @SuppressWarnings("unchecked")
76 public static <E> ImmutableList<E> of() {
77 return (ImmutableList<E>) EMPTY;
78 }
79
80
81
82
83
84
85
86
87
88 public static <E> ImmutableList<E> of(E element) {
89 return new SingletonImmutableList<E>(element);
90 }
91
92
93
94
95
96
97 public static <E> ImmutableList<E> of(E e1, E e2) {
98 return construct(e1, e2);
99 }
100
101
102
103
104
105
106 public static <E> ImmutableList<E> of(E e1, E e2, E e3) {
107 return construct(e1, e2, e3);
108 }
109
110
111
112
113
114
115 public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4) {
116 return construct(e1, e2, e3, e4);
117 }
118
119
120
121
122
123
124 public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5) {
125 return construct(e1, e2, e3, e4, e5);
126 }
127
128
129
130
131
132
133 public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
134 return construct(e1, e2, e3, e4, e5, e6);
135 }
136
137
138
139
140
141
142 public static <E> ImmutableList<E> of(
143 E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
144 return construct(e1, e2, e3, e4, e5, e6, e7);
145 }
146
147
148
149
150
151
152 public static <E> ImmutableList<E> of(
153 E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
154 return construct(e1, e2, e3, e4, e5, e6, e7, e8);
155 }
156
157
158
159
160
161
162 public static <E> ImmutableList<E> of(
163 E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
164 return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9);
165 }
166
167
168
169
170
171
172 public static <E> ImmutableList<E> of(
173 E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
174 return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
175 }
176
177
178
179
180
181
182 public static <E> ImmutableList<E> of(
183 E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11) {
184 return construct(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11);
185 }
186
187
188
189
190
191
192
193
194
195
196 public static <E> ImmutableList<E> of(
197 E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10, E e11, E e12,
198 E... others) {
199 Object[] array = new Object[12 + others.length];
200 array[0] = e1;
201 array[1] = e2;
202 array[2] = e3;
203 array[3] = e4;
204 array[4] = e5;
205 array[5] = e6;
206 array[6] = e7;
207 array[7] = e8;
208 array[8] = e9;
209 array[9] = e10;
210 array[10] = e11;
211 array[11] = e12;
212 System.arraycopy(others, 0, array, 12, others.length);
213 return construct(array);
214 }
215
216
217
218
219
220
221
222
223
224 public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {
225 checkNotNull(elements);
226 return (elements instanceof Collection)
227 ? copyOf((Collection<? extends E>) elements)
228 : copyOf(elements.iterator());
229 }
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250 public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {
251 if (elements instanceof ImmutableCollection) {
252 @SuppressWarnings("unchecked")
253 ImmutableList<E> list = ((ImmutableCollection<E>) elements).asList();
254 return list.isPartialView()
255 ? ImmutableList.<E>asImmutableList(list.toArray())
256 : list;
257 }
258 return construct(elements.toArray());
259 }
260
261
262
263
264
265
266 public static <E> ImmutableList<E> copyOf(Iterator<? extends E> elements) {
267
268 if (!elements.hasNext()) {
269 return of();
270 }
271 E first = elements.next();
272 if (!elements.hasNext()) {
273 return of(first);
274 } else {
275 return new ImmutableList.Builder<E>()
276 .add(first)
277 .addAll(elements)
278 .build();
279 }
280 }
281
282
283
284
285
286
287
288 public static <E> ImmutableList<E> copyOf(E[] elements) {
289 switch (elements.length) {
290 case 0:
291 return ImmutableList.of();
292 case 1:
293 return new SingletonImmutableList<E>(elements[0]);
294 default:
295 return new RegularImmutableList<E>(checkElementsNotNull(elements.clone()));
296 }
297 }
298
299
300
301
302 private static <E> ImmutableList<E> construct(Object... elements) {
303 return asImmutableList(checkElementsNotNull(elements));
304 }
305
306
307
308
309
310
311 static <E> ImmutableList<E> asImmutableList(Object[] elements) {
312 return asImmutableList(elements, elements.length);
313 }
314
315
316
317
318
319 static <E> ImmutableList<E> asImmutableList(Object[] elements, int length) {
320 switch (length) {
321 case 0:
322 return of();
323 case 1:
324 @SuppressWarnings("unchecked")
325 ImmutableList<E> list = new SingletonImmutableList<E>((E) elements[0]);
326 return list;
327 default:
328 if (length < elements.length) {
329 elements = arraysCopyOf(elements, length);
330 }
331 return new RegularImmutableList<E>(elements);
332 }
333 }
334
335 ImmutableList() {}
336
337
338
339 @Override public UnmodifiableIterator<E> iterator() {
340 return listIterator();
341 }
342
343 @Override public UnmodifiableListIterator<E> listIterator() {
344 return listIterator(0);
345 }
346
347 @Override public UnmodifiableListIterator<E> listIterator(int index) {
348 return new AbstractIndexedListIterator<E>(size(), index) {
349 @Override
350 protected E get(int index) {
351 return ImmutableList.this.get(index);
352 }
353 };
354 }
355
356 @Override
357 public int indexOf(@Nullable Object object) {
358 return (object == null) ? -1 : Lists.indexOfImpl(this, object);
359 }
360
361 @Override
362 public int lastIndexOf(@Nullable Object object) {
363 return (object == null) ? -1 : Lists.lastIndexOfImpl(this, object);
364 }
365
366 @Override
367 public boolean contains(@Nullable Object object) {
368 return indexOf(object) >= 0;
369 }
370
371
372
373
374
375
376
377
378
379 @Override
380 public ImmutableList<E> subList(int fromIndex, int toIndex) {
381 checkPositionIndexes(fromIndex, toIndex, size());
382 int length = toIndex - fromIndex;
383 switch (length) {
384 case 0:
385 return of();
386 case 1:
387 return of(get(fromIndex));
388 default:
389 return subListUnchecked(fromIndex, toIndex);
390 }
391 }
392
393
394
395
396
397
398 ImmutableList<E> subListUnchecked(int fromIndex, int toIndex) {
399 return new SubList(fromIndex, toIndex - fromIndex);
400 }
401
402 class SubList extends ImmutableList<E> {
403 transient final int offset;
404 transient final int length;
405
406 SubList(int offset, int length) {
407 this.offset = offset;
408 this.length = length;
409 }
410
411 @Override
412 public int size() {
413 return length;
414 }
415
416 @Override
417 public E get(int index) {
418 checkElementIndex(index, length);
419 return ImmutableList.this.get(index + offset);
420 }
421
422 @Override
423 public ImmutableList<E> subList(int fromIndex, int toIndex) {
424 checkPositionIndexes(fromIndex, toIndex, length);
425 return ImmutableList.this.subList(fromIndex + offset, toIndex + offset);
426 }
427
428 @Override
429 boolean isPartialView() {
430 return true;
431 }
432 }
433
434
435
436
437
438
439
440 @Deprecated
441 @Override
442 public final boolean addAll(int index, Collection<? extends E> newElements) {
443 throw new UnsupportedOperationException();
444 }
445
446
447
448
449
450
451
452 @Deprecated
453 @Override
454 public final E set(int index, E element) {
455 throw new UnsupportedOperationException();
456 }
457
458
459
460
461
462
463
464 @Deprecated
465 @Override
466 public final void add(int index, E element) {
467 throw new UnsupportedOperationException();
468 }
469
470
471
472
473
474
475
476 @Deprecated
477 @Override
478 public final E remove(int index) {
479 throw new UnsupportedOperationException();
480 }
481
482
483
484
485
486
487 @Override public final ImmutableList<E> asList() {
488 return this;
489 }
490
491 @Override
492 int copyIntoArray(Object[] dst, int offset) {
493
494 int size = size();
495 for (int i = 0; i < size; i++) {
496 dst[offset + i] = get(i);
497 }
498 return offset + size;
499 }
500
501
502
503
504
505
506
507
508
509 public ImmutableList<E> reverse() {
510 return new ReverseImmutableList<E>(this);
511 }
512
513 private static class ReverseImmutableList<E> extends ImmutableList<E> {
514 private final transient ImmutableList<E> forwardList;
515
516 ReverseImmutableList(ImmutableList<E> backingList) {
517 this.forwardList = backingList;
518 }
519
520 private int reverseIndex(int index) {
521 return (size() - 1) - index;
522 }
523
524 private int reversePosition(int index) {
525 return size() - index;
526 }
527
528 @Override public ImmutableList<E> reverse() {
529 return forwardList;
530 }
531
532 @Override public boolean contains(@Nullable Object object) {
533 return forwardList.contains(object);
534 }
535
536 @Override public int indexOf(@Nullable Object object) {
537 int index = forwardList.lastIndexOf(object);
538 return (index >= 0) ? reverseIndex(index) : -1;
539 }
540
541 @Override public int lastIndexOf(@Nullable Object object) {
542 int index = forwardList.indexOf(object);
543 return (index >= 0) ? reverseIndex(index) : -1;
544 }
545
546 @Override public ImmutableList<E> subList(int fromIndex, int toIndex) {
547 checkPositionIndexes(fromIndex, toIndex, size());
548 return forwardList.subList(
549 reversePosition(toIndex), reversePosition(fromIndex)).reverse();
550 }
551
552 @Override public E get(int index) {
553 checkElementIndex(index, size());
554 return forwardList.get(reverseIndex(index));
555 }
556
557 @Override public int size() {
558 return forwardList.size();
559 }
560
561 @Override boolean isPartialView() {
562 return forwardList.isPartialView();
563 }
564 }
565
566 @Override public boolean equals(@Nullable Object obj) {
567 return Lists.equalsImpl(this, obj);
568 }
569
570 @Override public int hashCode() {
571 int hashCode = 1;
572 int n = size();
573 for (int i = 0; i < n; i++) {
574 hashCode = 31 * hashCode + get(i).hashCode();
575
576 hashCode = ~~hashCode;
577
578 }
579 return hashCode;
580 }
581
582
583
584
585
586 static class SerializedForm implements Serializable {
587 final Object[] elements;
588 SerializedForm(Object[] elements) {
589 this.elements = elements;
590 }
591 Object readResolve() {
592 return copyOf(elements);
593 }
594 private static final long serialVersionUID = 0;
595 }
596
597 private void readObject(ObjectInputStream stream)
598 throws InvalidObjectException {
599 throw new InvalidObjectException("Use SerializedForm");
600 }
601
602 @Override Object writeReplace() {
603 return new SerializedForm(toArray());
604 }
605
606
607
608
609
610 public static <E> Builder<E> builder() {
611 return new Builder<E>();
612 }
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630 public static final class Builder<E> extends ImmutableCollection.ArrayBasedBuilder<E> {
631
632
633
634
635 public Builder() {
636 this(DEFAULT_INITIAL_CAPACITY);
637 }
638
639
640 Builder(int capacity) {
641 super(capacity);
642 }
643
644
645
646
647
648
649
650
651 @Override public Builder<E> add(E element) {
652 super.add(element);
653 return this;
654 }
655
656
657
658
659
660
661
662
663
664 @Override public Builder<E> addAll(Iterable<? extends E> elements) {
665 super.addAll(elements);
666 return this;
667 }
668
669
670
671
672
673
674
675
676
677 @Override public Builder<E> add(E... elements) {
678 super.add(elements);
679 return this;
680 }
681
682
683
684
685
686
687
688
689
690 @Override public Builder<E> addAll(Iterator<? extends E> elements) {
691 super.addAll(elements);
692 return this;
693 }
694
695
696
697
698
699 @Override public ImmutableList<E> build() {
700 return asImmutableList(contents, size);
701 }
702 }
703 }